﻿using System;
using System.Net;
using System.Threading;
using System.Collections.Generic;

//自定义命名空间
using DreamCube.Framework.Utilities.Log;
using DreamCube.Foundation.Basic.Extensions.System;

namespace DreamCube.Apps.WinForm.Common.DotNetWebServer
{
    public static class Utility
    {

        /// <summary>
        /// 获取本地服务器的Url前缀
        /// </summary>
        /// <param name="port">端口号</param>
        /// <returns></returns>
        public static String[] GetLocalServerHttpUrlPrefix(Int32 port = 80)
        {
            try
            {
                String prefixTemplate = port == 80 ? "http://{0}/" : "http://{0}:{1}/";
                String hostName = Dns.GetHostName();
                String[] ipAddresses = Utility.GetLocalIPAddress();
                List<String> prefixs = new List<String>();
                for (Int32 i = 0; i < ipAddresses.Length; i++)
                    prefixs.Add(prefixTemplate.FormatEx(ipAddresses[i], port.ToString()));

                prefixs.Add(prefixTemplate.FormatEx(hostName, port.ToString()));
                prefixs.Add(prefixTemplate.FormatEx("localhost", port.ToString()));
                prefixs.Add(prefixTemplate.FormatEx("127.0.0.1", port.ToString()));
                return prefixs.ToArray();
            }
            catch (Exception ex)
            {
                LoggerManager.Logger.MakeLog(ex);
            }
            return null;
        }

        /// <summary>
        /// 获取本机的IP地址
        /// </summary>
        /// <returns></returns>
        public static String[] GetLocalIPAddress()
        {
            try
            {
                List<String> ipAddress = new List<String>();
                IPHostEntry entry = Dns.GetHostEntry(Dns.GetHostName());
                if (entry != null && entry.AddressList.Length > 0)
                    for (Int32 i = 0; i < entry.AddressList.Length; i++)
                        if (entry.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                            ipAddress.Add(entry.AddressList[i].ToString());
                return ipAddress.ToArray();
            }
            catch (Exception ex)
            {
                LoggerManager.Logger.MakeLog(ex);
            }
            return null;
        }

        /// <summary>
        /// 获取网站的默认文档名
        /// </summary>
        /// <returns></returns>
        public static String[] GetDefualtDocuments()
        {
            try
            {
                String[] defaultDocuments = { "default.aspx", "default.htm", "default.html", "index.htm", "index.html" };
                return defaultDocuments;
            }
            catch (Exception ex)
            {
                LoggerManager.Logger.MakeLog(ex);
                return null;
            }
        }

        /// <summary>
        /// 获取禁止浏览的目录名称
        /// </summary>
        /// <returns></returns>
        public static String[] GetDefaultRestrictedDirs()
        {
            try
            {
                String[] restrictedDirs = { "/bin", "/app_browsers", "/app_code", "/app_data", "/app_localresources", "/app_globalresources", "/app_webreferences" };
                return restrictedDirs;
            }
            catch (Exception ex)
            {
                LoggerManager.Logger.MakeLog(ex);
                return null;
            }
        }

        /// <summary>
        /// 格式化虚拟目录，把目录格式化成统一的虚拟目录格式，虚拟目录格式统一为：/path；
        /// 也就是字符串的前面有反斜杠符，并且所有符号均是反斜杠符号，没有斜杠符
        /// </summary>
        /// <param name="virtualPath"></param>
        /// <returns></returns>
        public static String FormatVirtualPath(String virtualPath)
        {
            if (virtualPath.IsNullOrEmpty())
                return "/";

            virtualPath = virtualPath.Replace("\\", "/");

            if (!virtualPath.StartsWith("/"))
                virtualPath = "/" + virtualPath;

            return virtualPath;
        }

        /// <summary>
        /// 格式化HttpListener监听的Url串，串必须是以反斜杠（"/"）结尾，并且不能包含斜杠符号
        /// </summary>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public static String FormatHttpListenerPrefix(String prefix)
        {
            if (prefix.IsNullOrEmpty())
                return prefix;

            prefix = prefix.Replace("\\", "/");

            if (!prefix.EndsWith("/"))
                prefix += "/";

            return prefix;
        }

        /// <summary>
        /// 格式化HttpListener监听的Url串，串必须是以反斜杠（"/"）结尾，并且不能包含斜杠符号
        /// </summary>
        /// <param name="prefixs"></param>
        /// <returns></returns>
        public static String[] FormatHttpListenerPrefix(String[] prefixs)
        {
            try
            {
                if (prefixs == null || prefixs.Length == 0) return null;
                for (Int32 i = 0; i < prefixs.Length; i++)
                {
                    prefixs[i] = FormatHttpListenerPrefix(prefixs[i]);
                }
                return prefixs;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 根据请求的上下文验证请求的Url是否合法
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static Boolean ValidateRequestUrl(HttpListenerContext context)
        {
            try
            {
                String url = context.Request.RawUrl.ToString();
                if (url.IndexOf(".") > -1)
                {
                    if (!url.EndsWith("/"))
                        return true;
                    else
                    {
                        ThreadPool.QueueUserWorkItem((obj) =>
                        { context.Response.Redirect(context.Request.Url.ToString().LeftOfLast("/")); context.Response.Close(); });
                        return false;
                    }
                }

                if (!url.EndsWith("/"))
                {
                    ThreadPool.QueueUserWorkItem((obj) =>
                    { context.Response.Redirect(context.Request.Url.ToString() + "/"); context.Response.Close(); });
                    return false;
                }

                return true;
            }
            catch (Exception ex)
            {
                LoggerManager.Logger.MakeLogAsync(ex);
            }
            return false;
        }

        /// <summary>
        /// 格式化物理路径
        /// </summary>
        /// <param name="physicalPath"></param>
        /// <returns></returns>
        public static String FormatPhysicalPath(String physicalPath)
        {
            if (physicalPath.IsNullOrEmpty())
                return String.Empty;

            physicalPath = physicalPath.Replace("/", "\\");

            if (!physicalPath.EndsWith("\\"))
                physicalPath += "\\";

            return physicalPath;
        }
    }
}
